#https://github.com/wcmbishop/rayshader-demo/blob/master/R/find-image-coordinates.R
find_image_coordinates <- function(long, lat, bbox, image_width, image_height) {
x_img <- round(image_width * (long - min(bbox$p1$long, bbox$p2$long)) / abs(bbox$p1$long - bbox$p2$long))
y_img <- round(image_height * (1 - (lat - min(bbox$p1$lat, bbox$p2$lat)) / abs(bbox$p1$lat - bbox$p2$lat)))
list(x = x_img, y = y_img)
}
n_frames <- 120 # increase n_frames from 100 to 120
zscale <- 30
# frame transition variables
min_depth_coeff <- 0.5
max_depth_coeff <- 2
waterdepthvalues <- mean(elev_matrix) * min_depth_coeff - (mean(elev_matrix) * (max_depth_coeff - min_depth_coeff)) * cos(seq(0, 2 * pi, length.out = n_frames)) ## adjust water depth range
thetavalues <- -90 + 45 * cos(seq(0, 2*pi, length.out = n_frames))
# labels
label1 <- list(text = "Honolulu")
label1$lon <- -157.8581
label1$lat <- 21.3099
label2 <- list(text = "Pearl City")
label2$lon <- -157.9715
label2$lat <- 21.3910
cat("Heightmap dimensions:", dim(elev_matrix), "\n")
cat("Label1 coordinates:", label1$pos$x, label1$pos$y, "\n")
cat("Label2 coordinates:", label2$pos$x, label2$pos$y, "\n")
# generate .png frame images
img_frames <- paste0("drain", seq_len(n_frames), ".png")
for (i in seq_len(n_frames)) {
message(paste(" - image", i, "of", n_frames))
elev_matrix %>%
sphere_shade(texture = "imhof4") %>%
add_water(watermap, color = "imhof3") %>%
plot_3d(elev_matrix, solid = TRUE, shadow = TRUE, zscale = zscale,
water = TRUE, watercolor = "imhof3", wateralpha = 0.8,
waterlinecolor = "#ffffff", waterlinealpha = 0.5,
waterdepth = waterdepthvalues[i]/zscale,
theta = thetavalues[i], phi = 45)
# find relative image coordinates based on lon, lat of labels
label1$pos <- find_image_coordinates(label1$lon, label1$lat, bbox, image_size$width, image_size$height)
label2$pos <- find_image_coordinates(label2$lon, label2$lat, bbox, image_size$width, image_size$height)
render_label(elev_matrix, x = label1$pos$x, y = label1$pos$y, z = 500,
zscale = zscale, text = label1$text, textsize = 1, linewidth = 3)
render_label(elev_matrix, x = label2$pos$x, y = label2$pos$y, z = 500,
zscale = zscale, text = label2$text, textsize = 1, linewidth = 3)
render_snapshot(img_frames[i])
rgl::clear3d()
}
# build gif
magick::image_write_gif(magick::image_read(img_frames),
path = "water_rise.gif",
delay = 12/n_frames) # increase delay for smoother animation